/*
 * Copyright (c) 2014 laidian. All Rights Reserved.
 * 
 * @author yaoyuming
 * 
 * @date 2020-04-01 14:32
 */
package com.yao.home;

import cn.hutool.core.thread.ThreadUtil;
import com.yao.common.resp.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author yaoyuming
 * @date 2020/04/01 14:32
 */
@RestController
@RequestMapping("/test")
@Slf4j
public class TestController {

    private List<Integer> intList = new LinkedList<>();

    /**
     * 功能描述 : Springboot中的@EnableAsync和@Async的作用和基本用法
     *
     * @author yaoyuming
     * @date 2020/4/1
     * @return {@link }
     */
    @GetMapping("/blocking")
    public ApiResponse<Object> blocking() {
        // 同步（阻塞）
        log();
        return ApiResponse.success();
    }

    @GetMapping("/async1")
    public ApiResponse<Object> async1() {
        asyncPrint_1();
        return ApiResponse.success();
    }

    // 3中异步方式

    // 线程池的方式被注解代替 @EnableAsync @Async;
    @GetMapping("/async2")
    @Async
    public ApiResponse<Object> async2() {
        log();
        return ApiResponse.success();
    }

    // 1. 使用线程池实现
    private void asyncPrint_1() {
        System.out.println("获取主线程名称 = " + Thread.currentThread().getName());
        /**
         * 定义一个线程池 核心线程数（corePoolSize）:1 最大线程数（maximumPoolSize）: 1 保持连接时间（keepAliveTime）：50000 时间单位
         * (TimeUnit):TimeUnit.MILLISECONDS(毫秒) 阻塞队列 new LinkedBlockingQueue<Runnable>()
         */
        ThreadPoolExecutor executor =
            new ThreadPoolExecutor(5, 5, 1000L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

        // 执行业务逻辑方法
        executor.execute(new Runnable() {
            @Override
            public void run() {
                log();
            }
        });
        System.out.println("异步方法1执行完成");
    }

    // 业务逻辑 打印数字
    private void log() {
        Arrays.stream(new int[] {1, 1, 3, 3, 4, 5, 6, 7, 87, 8, 98}).forEach(e -> {
            ThreadUtil.safeSleep(1000L);
            System.out.println("e = " + e);
        });
    }


    @Autowired
    private AsyncService asyncService;

    // 异步读、写测试
    @GetMapping("/async3")
    public ApiResponse<Void> async3() throws InterruptedException {
        log.info("当前线程: "+Thread.currentThread().getName());
        asyncService.write();
        asyncService.read();
        return ApiResponse.success();
    }


}